// 负责创建 Axios 实例并初始化核心功能
/* 发起请求的能力（通过 request 方法绑定和函数调用）。
灵活的配置系统（默认配置、用户配置合并、自定义实例）。
拦截器管理（通过 interceptors 属性，支持请求 / 响应预处理）。
请求取消（挂载 CancelToken 等类，支持中断未完成的请求）。 */
import Axios from "./core/Axios"
import { AxiosRequestConfig, AxiosStatic } from "./types"
import { extend } from "./helpers/util"
import defaults from "./defaults"
import mergeConfig from "./core/mergeConfig"
import CancelToken from "./cancel/CancelToken"
import Cancel, { isCancel } from "./cancel/Cancel"

function createInstance(config: AxiosRequestConfig): AxiosStatic {
  const context = new Axios(config)  // 创建一个 Axios 类的实例 context，这个实例包含 Axios 的核心功能（如拦截器、默认配置等）
  const instance = Axios.prototype.request.bind(context) // 用 bind(context) 固定request 方法的 this 为 context。让 instance(url, config) 等价于 context.request({ method: 'get', url, ...config }) 此时 instance 只是一个 函数，仅有发起请求的能力  但 没有 context 的其他属性（如 interceptors、create、CancelToken 等）
  extend(instance, context)// 3. 将 context 的属性复制到 instance 上
  return instance as AxiosStatic// 4. 类型断言，返回最终的 axios 实例
}

const axios = createInstance(defaults)// 创建 axios 实例，传入默认配置defaults

axios.create = function create(config) {// axios.create 能被调用，是因为提前通过 axios.create = function() {} 挂载了方法，而 .create 只是访问这个已挂载的方法。
  return createInstance(mergeConfig(defaults, config))// 合并默认配置和用户配置
}

// 挂载取消相关类（支持请求取消功能）
axios.CancelToken = CancelToken// 挂载取消令牌类（用于生成取消令牌）
axios.Cancel = Cancel// 挂载取消错误类（用于创建取消错误对象）
axios.isCancel = isCancel// 挂载取消判断函数（判断错误是否为取消错误）

axios.all = function all(promises) { //用于同时发起多个请求并等待全部完成，类似 Promise.all
  return Promise.all(promises)
}

axios.spread = function spread(callback) {
  return function wrap(arr) {
    return callback.apply(null, arr)// 将数组参数展开为函数参数
  }
}

axios.Axios = Axios  // 将 Axios 类挂载到axios 实例上
export default axios